//TO DO 后续还可以将抽象路径做成配置型
// 实现这个项目的构建任务

//倒入gulp下需要使用的库
const { src, dest,parallel, series, watch } = require('gulp')
const del = require('del')

//自动加载插件
const loadPlugins = require('gulp-load-plugins')
const plugins = loadPlugins()
const { sass, babel, swig, imagemin, uglify, cleanCss, htmlmin } = plugins

//通过开发服务器，在代码修改后能够热更新
const browserSync = require('browser-sync')
const bs = browserSync.create()
const data = {
    menus: [
      {
        name: 'Home',
        icon: 'aperture',
        link: 'index.html'
      },
      {
        name: 'Features',
        link: 'features.html'
      },
      {
        name: 'About',
        link: 'about.html'
      },
      {
        name: 'Contact',
        link: '#',
        children: [
          {
            name: 'Twitter',
            link: 'https://twitter.com/w_zce'
          },
          {
            name: 'About',
            link: 'https://weibo.com/zceme'
          },
          {
            name: 'divider'
          },
          {
            name: 'About',
            link: 'https://github.com/zce'
          }
        ]
      }
    ],
    pkg: require('./package.json'),
    date: new Date()
}

//文件清除
const clean =()=>{
    return del(['dist','temp'])
}

//样式编译
const style=()=>{
    return src('src/assets/styles/*.scss',{base:'src'})
        .pipe(sass({outputStyle:'expanded'}))
        .pipe(dest('temp'))
        .pipe(bs.reload({stream: true}))
}

// 脚本编译
const script = () => {
    return src('src/assets/scripts/*.js', { base: 'src'})
        .pipe(babel({presets: ['@babel/preset-env']}))
        .pipe(dest('temp'))
        .pipe(bs.reload({stream: true}))
}

// 模板编译
const page = () => {
    return src('src/*.html', { base: 'src'})
        .pipe(swig({data, defaults: {cache: false}})) // 防止模板缓存导致页面不能及时更新
        .pipe(dest('temp'))
        .pipe(bs.reload({stream: true}))
}


// 图片压缩
const image = () => {
    return src('src/assets/images/**', { base: 'src'})
        .pipe(imagemin())
        .pipe(dest('dist'))
}

// 字体压缩
const font = () => {
    return src('src/assets/fonts/**', { base: 'src'})
        .pipe(imagemin())
        .pipe(dest('dist'))
}

// 额外的编译：public
const extra = () => {
    return src('public/**', {base: 'public'})
        .pipe(dest('dist'))
}


// 开发服务器
const server = () => {
    // 监视文件，决定是否要执行任务
    watch('src/assets/styles/*.scss', style)
    watch('src/assets/scripts/*.js', script)
    watch('src/*.html', page)
    //watch('src/assets/images/**', image)
    //watch('src/assets/fonts/**', font)
    //watch('public/**', extra)

    watch([
        'src/assets/images/**',
        'src/assets/fonts/**',
        'public/**'
    ], bs.reload)

    // 初始化服务器的相关配置
    bs.init({
        notify:false, 
        port:2080,
        // files:'dist/**',
        server: {
            baseDir:['temp', 'src', 'public'],//图片只是压缩了，请求dist和src上并无区别，只是进行压缩了下，这里让他请求原文件，减少了一次构建，提高开发效率
            routes:{
                '/node_modules' : 'node_modules'
            }
        }
    })
}

// 文件引用处理---合并
const useref = () => {
    return src('temp/*.html',{base: 'temp'})
        .pipe(plugins.useref({searchPath: ['temp','.']}))
        .pipe(plugins.if(/\.js$/,uglify()))
        .pipe(plugins.if(/\.css$/,cleanCss()))
        .pipe(plugins.if(/\.html$/,htmlmin({
            collapseWhitespace: true, // 折叠空白字符和换行符
            minifyCSS: true, // 样式压缩
            minefyJS: true // 脚本压缩
        })))
        .pipe(dest('dist'))
}
// 编译任务
const compile = parallel(style, script, page)

// 完成所有文件的编译   上线之前执行的任务
const build = series(
    clean,
    parallel(     
        series(compile, useref), 
        image, 
        font, 
        extra
    )
)

// 开发任务
const develop = series(compile, server)
module.exports = {
    build,
    develop,
    compile,

    style,
    script,
    page,
    useref
}

/**
 * 运行命令
 * yarn gulp build
 * yarn gulp develop
 * yarn gulp compile
 */